package org.gap.jseed;

import java.lang.reflect.Constructor;

/**
 * Used for constructing an instance of the service class with the
 * provided arguments.
 * @author gpelcha
 *
 */
public class ServiceBuilder<E> implements Builder<E> {
	private final Class<? extends E> service;
	private final Object[] arguments;
	private Constructor<?> constructor;

	public ServiceBuilder(Class<? extends E> service, Object...arguments) throws SecurityException {
		this.service = service;
		this.arguments = arguments;
		try {
			constructor = new ArgumentsToConstructorMatcher(service, arguments).getConstructor();
		} catch (NoSuchMethodException nsme) {
			throw new IllegalStateException(String.format("%s is not a valid argument for %s", arguments[0], service.getName()), nsme);
		}
	}

	@Override
	public Class<? extends E> getType() {
		return service;
	}
	
	@Override
	public E createInstance()  {
		try {
			// The type has already been validated by the constructor.
			@SuppressWarnings("unchecked") E result = (E)constructor.newInstance(arguments);
			return result;
		} catch (Exception e) {
			throw new RuntimeException("Unexpected error occured", e);
		}
	}
}
